<?php
/** 
 * Plugin 'rdt_lister' for the 'ameos_formidable' extension.
 *
 * @author	Jerome Schneider <typo3dev@ameos.com>
 */


class tx_rdtlister extends formidable_mainrenderlet {

	var $aLibs = array(
		"rdt_lister_class" => "res/js/lister.js",
	);

	var $sMajixClass = "Lister";

	var $bCustomIncludeScript = TRUE;

	var $oDataStream = FALSE;
	var $sDsType = FALSE;
	var $aOColumns = FALSE;
	var $aPager = FALSE;
	var $aLimitAndSort = FALSE;
	var $bDefaultTemplate = FALSE;
	var $bNoTemplate = FALSE;
	var $bResetPager = FALSE;

	var $aRdtByRow = array();

	var $iCurRowNum = FALSE;

	function _render() {

		$this->_initDataStream();
		#$this->aLimitAndSort = FALSE;
		$this->_initLimitAndSort();

		$this->aRdtByRow = array();

		$aData = $this->_fetchData(
			$aConfig = array(
				"page" => ($this->aLimitAndSort["curpage"] - 1),
				"perpage" => $this->aLimitAndSort["rowsperpage"],
				"sortcolumn" => $this->aLimitAndSort["sortby"],
				"sortdirection" => $this->aLimitAndSort["sortdir"],
			)
		);

		if(intval($aData["numrows"]) === 0) {
			if(($mEmpty = $this->_navConf("/ifempty")) !== FALSE) {
				if(is_array($mEmpty)) {
					if($this->oForm->_defaultTrue("/process", $mEmpty) === FALSE) {
						return array(
							"__compiled" => "",
							"pager." => array(
								"numrows" => 0,
							)
						);
					}

					if($this->oForm->_navConf("/message", $mEmpty) !== FALSE) {
						if($this->oForm->isRunneable($mEmpty["message"])) {
							$sMessage = $this->callRunneable($mEmpty["message"]);
						} else {
							$sMessage = $mEmpty["message"];
						}

						return array(
							"__compiled" => $this->oForm->_getLLLabel($sMessage),
							"pager." => array(
								"numrows" => 0,
							)
						);
					}
				} else {
					return array(
						"__compiled" => $this->oForm->_getLLLabel($mEmpty),
						"pager." => array(
							"numrows" => 0,
						)
					);
				}
			}
		}

		$this->_initPager($aData["numrows"]);

		$sAddParams = $this->_getAddInputParams();

		$aHtmlBag = array(
			"__compiled" => $this->_wrapIntoContainer($this->_renderList($aData), $sAddParams),
			"addparams" => $sAddParams,
			"pager." => array(
				"display" => ($this->aPager["display"] === TRUE) ? "1" : "0",
				"page" => $this->aPager["page"],
				"pagemax" => $this->aPager["pagemax"],
				"offset" => $this->aPager["offset"],
				"numrows" => $this->aPager["numrows"],
				"links." => array(
					"first" => $this->aPager["links"]["first"],
					"prev" => $this->aPager["links"]["prev"],
					"next" => $this->aPager["links"]["next"],
					"last" => $this->aPager["links"]["last"],
				),
				"rowsperpage" => $this->aLimitAndSort["rowsperpage"],
				"limitoffset" => $this->aLimitAndSort["limitoffset"],
				"limitdisplayed" => $this->aLimitAndSort["limitdisplayed"],
				"sortby" => $this->aLimitAndSort["sortby"],
				"sortdir" => $this->aLimitAndSort["sortdir"],
			),
		);
		
		$this->includeScripts(
			array(
				"rdtbyrow" => $this->aRdtByRow,
			)
		);

		return $aHtmlBag;
	}

	function _wrapIntoContainer($sHtml, $sAddParams = "") {
		if($this->isInline()) {
			$sBegin = "<!--BEGIN:LISTER:inline:" . $this->_getElementHtmlId() . "-->";
			$sEnd = "<!--END:LISTER:inline:" . $this->_getElementHtmlId() . "-->";
			return $sBegin . $sHtml . $sEnd;
		} elseif($this->bDefaultTemplate === TRUE) {
			return "<div id=\"" . $this->_getElementHtmlId() . "\" class=\"ameosformidable-rdtlister-defaultwrap\"" . $sAddParams . ">" . $sHtml . "</div>";
		} elseif($this->bNoTemplate === TRUE) {
			return $sHtml;
		} else {
			return "<div id=\"" . $this->_getElementHtmlId() . "\"" . $sAddParams . ">" . $sHtml . "</div>";
		}
	}

	function isInline() {
		return $this->_navConf("/mode") === "inline";
	}

	function _initDataStream() {
		
		if($this->oDataStream === FALSE) {

			if(($sDsToUse = $this->_navConf("/searchform/use")) === FALSE) {
				if(($sDsToUse = $this->_navConf("/datasource/use")) === FALSE) {
					$this->oForm->mayday("RENDERLET LISTER <b>" . $this->_getName() . "</b> - requires <b>/datasource/use</b> OR <b>/searchform/use</b> to be properly set. Check your XML conf.");
				} else {
					if(!array_key_exists($sDsToUse, $this->oForm->aODataSources)) {
						$this->oForm->mayday("RENDERLET LISTER <b>" . $this->_getName() . "</b> - refers to undefined datasource '" . $sDsToUse . "'. Check your XML conf.");
					} else {
						$this->oDataStream =& $this->oForm->aODataSources[$sDsToUse];
						$this->sDsType = "datasource";
					}
				}
			} else {
				if(!array_key_exists($sDsToUse, $this->oForm->aORenderlets)) {
					$this->oForm->mayday("RENDERLET LISTER - refers to undefined searchform '" . $sDsToUse . "'. Check your XML conf.");
				} elseif(($sDsType = $this->oForm->aORenderlets[$sDsToUse]->_getType()) !== "SEARCHFORM") {
					$this->oForm->mayday("RENDERLET LISTER - defined searchform <b>'" . $sDsToUse . "'</b> is not of <b>SEARCHFORM</b> type, but of <b>" . $sDsType . "</b> type");
				} else {
					$this->oDataStream =& $this->oForm->aORenderlets[$sDsToUse];
					$this->sDsType = "searchform";
					if($this->oDataStream->shouldUpdateCriterias()) {
						$this->bResetPager = TRUE;
					}
				}
			}
		}
	}

	function _initLimitAndSort() {

		if($this->aLimitAndSort === FALSE) {
			$iCurPage = $this->_getPage();
			$iRowsPerPage = 5;	// default value

			if(($mRowsPerPage = $this->_navConf("/pager/rows/perpage")) !== FALSE) {
				if($this->oForm->isRunneable($mRowsPerPage)) {
					$mRowsPerPage = $this->callRunneable($mRowsPerPage);
				}
				
				if(intval($mRowsPerPage) > 0) {
					$iRowsPerPage = $mRowsPerPage;
				} elseif(intval($mRowsPerPage) === -1) {
					$iRowsPerPage = 1000000;
				}
			}

			$aSort = $this->_getSortColAndDirection();

			if(trim($aSort["col"]) !== "" && array_key_exists($aSort["col"], $this->aOColumns)) {
				if(($sRealSortCol = $this->aOColumns[$aSort["col"]]->_navConf("/sortcol")) === FALSE) {
					$sRealSortCol = $aSort["col"];
				}
			} else {
				$sRealSortCol = $aSort["col"];
			}

			$this->aLimitAndSort = array(
				"curpage" => $iCurPage,
				"rowsperpage" => $iRowsPerPage,
				"limitoffset" => ($iCurPage - 1) * $iRowsPerPage,
				"limitdisplayed" => $iRowsPerPage,
				"sortby" => $sRealSortCol,
				"sortdir" => $aSort["dir"],
			);
		}
	}

	function _initPager($iNumRows) {

		$iPageMax = (ceil($iNumRows/ $this->aLimitAndSort["rowsperpage"]));
		
		if($iPageMax > 1 || $this->_defaultFalse("/pager/alwaysdisplay")) {
			$bDisplay = TRUE;
		} else {
			$bDisplay = FALSE;
		}

		// generating javascript links & functions

		$sLinkFirst = $sLinkPrev = $sLinkNext = $sLinkLast = "";

		if($iPageMax >= 1) {

			if($this->aLimitAndSort["curpage"] > 1) {

				$sLinkFirst = $this->_buildLink(array(
					"page" => 1
				));

				$sLinkPrev = $this->_buildLink(array(
					"page" => $this->aLimitAndSort["curpage"] - 1
				));

			}
			
			// print 'next' link only if we're not
			// on the last page
			
			if($this->aLimitAndSort["curpage"] < $iPageMax) {

				$sLinkNext = $this->_buildLink(array(
					"page" => ($this->aLimitAndSort["curpage"] + 1)
				));

				$sLinkLast = $this->_buildLink(array(
					"page" => $iPageMax
				));
			}
		}

		$iPage = ($iPageMax == 0) ? 0 : $this->aLimitAndSort["curpage"];
		$bAlwaysFullWidth = FALSE;

		$aWindow = array();

		if(($mWindow = $this->_navConf("/pager/window")) !== FALSE && $iNumRows > 0) {

			if($this->oForm->isRunneable($mWindow)) {
				$iWindowWidth = $this->callRunneable($mWindow);
			} elseif(is_array($mWindow) && (($mWidth = $this->_navConf("/pager/window/width")) !== FALSE)) {
				if($this->oForm->isRunneable($mWidth)) {
					$mWidth = $this->callRunneable($mWidth);
				}
				
				$iWindowWidth = intval($mWidth);

				if(($mAlwaysFullWidth = $this->_defaultFalse("/pager/window/alwaysfullwidth")) !== FALSE) {
					if($this->oForm->isRunneable($mAlwaysFullWidth)) {
						$mAlwaysFullWidth = $this->callRunneable($mAlwaysFullWidth);
					}

					$bAlwaysFullWidth = $mAlwaysFullWidth;
				}
			} else {
				$iWindowWidth = $mWindow;
			}

			if($iWindowWidth !== FALSE) {

				// generating something like < 24 25 *26* 27 28 >

				/*
					window pager patch by Manuel Rego Casasnovas
					@see http://lists.netfielders.de/pipermail/typo3-project-formidable/2008-January/000816.html
				*/


				$iStart = $iPage - ($iWindowWidth - 1);
				if($iStart < 1) {
					$iStart = 1;
				}
				
				if($iStart == 1) {
					$sLinkFirst = "";
				}
				
				#$iEnd = $iPage + 1;
				#$iEnd = $iPage + ($iWindowWidth - 2);
				$iEnd = $iPage + ($iWindowWidth - 1);

				if($iEnd > $iPageMax) {
					$iEnd = $iPageMax;
				}

				if($iEnd == $iPageMax) {
					$sLinkLast = "";
				}

				if(($iPageMax + 1) < $iWindowWidth) {
					$iEnd = $iWindowWidth;
				}
				
				for($k = $iStart; $k <= $iEnd; $k++) {
					if($k <= $iPageMax) {
						$aWindow[$k] = $this->_buildLink(array(
							"page" => $k
						));
					} else {
						$aWindow[$k] = FALSE;
					}
				}
			}
		}

		$this->aPager = array(
			"display"	=>	$bDisplay,
			"numrows"	=>	$iNumRows,
			"offset"	=>	$this->aLimitAndSort["limitoffset"],
			"page"		=>	$iPage,
			"pagemax"	=>	$iPageMax,
			"rowsperpage" => $this->aLimitAndSort["rowsperpage"],
			"links"		=>	array(
				"first"		=>	$sLinkFirst,
				"prev"		=>	$sLinkPrev,
				"next"		=>	$sLinkNext,
				"last"		=>	$sLinkLast,
			),
			"window"	=>	$aWindow,
			"alwaysfullwidth" => $bAlwaysFullWidth,
		);
	}

	function _buildLink($aParams, $aExcludeParams = array()) {

		$aRdtParams = array(
			$this->oForm->formid => array(
				$this->_getElementHtmlId() => $aParams
			)
		);

		$sEnvMode = $this->oForm->__getEnvExecMode();
		if($sEnvMode === "BE") {
			$sBaseUrl = t3lib_div::getIndpEnv("TYPO3_REQUEST_URL");
			$aQueryParts = parse_url($sBaseUrl);
			$aParams = array();
			if($aQueryParts['query']) {
				parse_str($aQueryParts['query'], $aParams);
			}
		} elseif($sEnvMode === "EID") {
			$sBaseUrl = t3lib_div::getIndpEnv("HTTP_REFERER");
			$aQueryParts = parse_url($sBaseUrl);
			$aParams = array();
			if($aQueryParts['query']) {
				parse_str($aQueryParts['query'], $aParams);
			}
		} elseif($sEnvMode === "FE") {
			$aParams = t3lib_div::_GET();
		}


		$aFullParams = t3lib_div::array_merge_recursive_overrule(
			$aParams,
			$aRdtParams
		);

		if(!empty($aExcludeParams)) {
			
			$aRdtParamsExclude = array(
				$this->oForm->formid => array(
					$this->_getElementHtmlId() => $aExcludeParams
				)
			);

			$aPathes = $this->oForm->implodePathesForArray($aRdtParamsExclude);
			reset($aPathes);
			while(list(, $sPath) = each($aPathes)) {
				$this->oForm->unsetDeepData(
					$sPath,
					$aFullParams
				);
			}
		}

		if(array_key_exists("cHash", $aFullParams)) {
			unset($aFullParams["cHash"]);
		}

		if($this->oForm->_defaultFalse("/cachehash", $this->aElement) === TRUE) {
			$aFullParams["cHash"] = t3lib_div::shortMD5(
				serialize(
					t3lib_div::cHashParams(
						t3lib_div::implodeArrayForUrl('',$aFullParams)
					)
				)
			);
		}

		if($sEnvMode === "BE" || $sEnvMode === "EID") {
			return $this->oForm->xhtmlUrl(
				t3lib_div::linkThisUrl(
					$sBaseUrl,
					$aFullParams
				)
			);
		} elseif($sEnvMode === "FE") {

			if(array_key_exists("id", $aFullParams)) {
				unset($aFullParams["id"]);
			}

			return $this->oForm->cObj->typolink_URL(array(
				"parameter" => $GLOBALS["TSFE"]->id,
				"additionalParams" => t3lib_div::implodeArrayForUrl(
					"",
					$aFullParams
				)
			));
		}
	}

	function &_fetchData($aConfig = FALSE) {
		if($aConfig === FALSE) {
			$this->_initDataStream();
			$this->_initColumns();
			$this->aLimitAndSort = FALSE;
			$this->_initLimitAndSort();

			return $this->_fetchData(
				$aConfig = array(
					"page" => ($this->aLimitAndSort["curpage"] - 1),
					"perpage" => $this->aLimitAndSort["rowsperpage"],
					"sortcolumn" => $this->aLimitAndSort["sortby"],
					"sortdirection" => $this->aLimitAndSort["sortdir"],
				)
			);
		} else {
			return $this->oDataStream->_fetchData($aConfig);
		}
	}

	function &_renderList(&$aRows) {

		$aTemplate = $this->_getTemplate();

		$this->_renderList_displayRows($aTemplate, $aRows);
		$this->_renderList_displayPager($aTemplate);
		$this->_renderList_displaySortHeaders($aTemplate);

		reset($this->aOColumns);
		while(list($sColumn, ) = each($this->aOColumns)) {
			$aTemplate["html"] = str_replace(
				"{" . $sColumn . ".label}",
				$this->getListHeader($sColumn),
				$aTemplate["html"]
			);
		}

		$aTemplate["html"] = $this->oForm->_substLLLInHtml($aTemplate["html"]);

		return $aTemplate["html"];
	}

	function getListHeader($sColumn) {

		if(($sLabel = $this->aOColumns[$sColumn]->_navConf("/listheader")) === FALSE) {
			
			$sAutoMap = "LLL:" . $this->aOColumns[$sColumn]->getAbsName() . ".listheader";
			if($this->oForm->sDefaultLLLPrefix !== FALSE && (($sAutoLabel = $this->oForm->_getLLLabel($sAutoMap)) !== "")) {
				return $sAutoLabel;
			}

			if(($sLabel = $this->aOColumns[$sColumn]->getLabel()) === "") {
				return "";
			}
		}

		if($this->oForm->isRunneable($sLabel)) {
			$sLabel = $this->oForm->callRunneable($sLabel);
		}

		return $this->oForm->_getLLLabel($sLabel);
	}

	function _renderList_displayRows(&$aTemplate, &$aRows) {
		
		$aRowsHtml = array();
		if($this->bNoTemplate !== TRUE) {
			$aAltRows = array();
			$aRowsHtml = array();
			$sRowsPart = t3lib_parsehtml::getSubpart($aTemplate["html"], "###ROWS###");

			if($aTemplate["default"] === TRUE) {
				$sAltList = "###ROW1###, ###ROW2###";
			}elseif(($sAltRows = $this->_navConf("/template/alternaterows")) !== FALSE && $this->oForm->isRunneable($sAltRows)) {
				$sAltList = $this->callRunneable($sAltRows);
			}elseif(($sAltList = $this->_navConf("/template/alternaterows")) === FALSE ){
				$this->oForm->mayday("RENDERLET LISTER <b>" . $this->_getName() . "</b> requires /template/alternaterows to be properly set. Please check your XML configuration");
			}

			$aAltList = t3lib_div::trimExplode(",", $sAltList);
			if(sizeof($aAltList) > 0) {
				reset($aAltList);
				while(list(, $sAltSubpart) = each($aAltList)) {
					$aAltRows[] = t3lib_parsehtml::getSubpart($sRowsPart, $sAltSubpart);
				}

				$iNbAlt = sizeOf($aAltRows);
			}
		}
		
		$aColKeys = array_keys($this->aOColumns);
		reset($aColKeys);
		while(list(,$sName) = each($aColKeys)) {	
			$this->aOColumns[$sName]->doBeforeListRender($this);
		}
		
		$iRowNum = 0;
		$this->iCurRowNum = 0;

		$aTableCols = FALSE;
		reset($aRows);
		while(list($iIndex, ) = each($aRows["results"])) {
			$this->iCurRowNum = $iRowNum;
			$aCurRow = $aRows["results"][$iIndex];
			
			if($aTableCols === FALSE) {
				$aTableCols = array_keys($aCurRow);
				reset($aTableCols);
			}

			$this->__aCurRow = $aCurRow;
			array_push($this->oForm->oDataHandler->__aListData, $aCurRow);
			$aCurRow = $this->processBeforeRender($aCurRow);
			$aCurRow = $this->_refineRow($aCurRow);
			$aCurRow = $this->processBeforeDisplay($aCurRow);


			$this->__aCurRow = array();

			$aCurRow = $this->filterUnprocessedColumns($aCurRow, $aTableCols);

			if($this->bNoTemplate === TRUE) {
				reset($this->aOColumns);
				while(list($sCol,) = each($this->aOColumns)) {
					$sRowHtml = $aCurRow[$sCol]["__compiled"];
				}
			} else {
				$sRowHtml = $this->oForm->_parseTemplateCode(
					$aAltRows[$iRowNum++ % $iNbAlt],		// current alternate subpart for row
					$aCurRow
				);
			}

			$aRowsHtml[] = $this->rowWrap($sRowHtml);
			array_pop($this->oForm->oDataHandler->__aListData);
		}

		$this->iCurRowNum = FALSE;
		
		$aColKeys = array_keys($this->aOColumns);
		reset($aColKeys);
		while(list(,$sName) = each($aColKeys)) {	
			$this->aOColumns[$sName]->doAfterListRender($this);
		}

		if($this->bNoTemplate === FALSE) {
			if($this->_defaultTrue("/template/allowincompletesequence") === FALSE) {
				$iNbResultsOnThisPage = count($aRows["results"]);
				if(($iNbResultsOnThisPage % $iNbAlt) !== 0) {
					for($k = $iRowNum % $iNbAlt; $k < $iNbAlt; $k++) {

						$aRowsHtml[] = $this->oForm->_parseTemplateCode(
							$aAltRows[$k],		// current alternate subpart for row
							array(),
							array(),
							FALSE
						);
					}
				}
			}

			$aTemplate["html"] = t3lib_parsehtml::substituteSubpart(
				$aTemplate["html"],
				"###ROWS###",
				implode("", $aRowsHtml),
				FALSE,
				FALSE
			);
		} else {
			$aTemplate["html"] = implode($aRowsHtml);
		}
	}

	function rowWrap($sHtmlRow) {
		if(($sWrap = $this->_navConf("/columns/wrap")) !== FALSE) {
			if($this->oForm->isRunneable($sWrap)) {
				$sWrap = $this->callRunneable($sWrap);
			}

			if(is_string($sWrap)) {
				return str_replace("|", $sHtmlRow, $this->oForm->_substLLLInHtml($sWrap));
			}
		}

		return $sHtmlRow;
	}

	function processBeforeRender($aRow) {
		
		if(($aBeforeRender = $this->_navConf("/beforerender")) !== FALSE && $this->oForm->isRunneable($aBeforeRender)) {
			$aRow = $this->callRunneable($aBeforeRender, $aRow);
		}

		return $aRow;
	}

	function processBeforeDisplay($aRow) {
		
		if(($aBeforeDisplay = $this->_navConf("/beforedisplay")) !== FALSE && $this->oForm->isRunneable($aBeforeDisplay)) {
			$aRow = $this->callRunneable($aBeforeDisplay, $aRow);
		}

		return $aRow;
	}

	function filterUnprocessedColumns($aRow, $aDataSetCols) {
		reset($aRow);
		while(list($sKey,) = each($aRow)) {
			if($sKey !== "uid" && !array_key_exists($sKey, $this->aOColumns) && in_array($sKey, $aDataSetCols)) {
				unset($aRow[$sKey]);
			}
		}

		reset($aRow);
		return $aRow;
	}

	function _renderList_displayPager(&$aTemplate) {

		if(($mHtml = $this->_navConf("/pager/html")) !== FALSE) {
			if($this->oForm->isRunneable($mHtml)) {
				$mHtml = $this->callRunneable($mHtml, $this->aPager);
			}

			$sPager = $mHtml;

		} elseif($this->aPager["display"] === TRUE) {
			$sPager = $aTemplate["pager"];
			$aLinks = array();
			
			$sPager = $this->oForm->_parseTemplateCode(
				$sPager,
				array(
					"page" => $this->aPager["page"],
					"pagemax" => $this->aPager["pagemax"]
				),
				array(),
				FALSE
			);
			
			
			reset($this->aPager["links"]);
			while(list($sWhich, $sLink) = each($this->aPager["links"])) {

				if($sLink !== "") {
					$aLinks[$sWhich] = $this->oForm->_parseTemplateCode(
						t3lib_parsehtml::getSubpart($sPager, "###LINK" . strtoupper($sWhich) . "###"),
						array(
							"link" => $sLink
						),
						array(),
						FALSE
					);
				} else {
					$aLinks[$sWhich] = "";
				}
			}

			$sPager = t3lib_parsehtml::substituteSubpart($sPager, "###LINKFIRST###",$aLinks["first"], FALSE, FALSE);
			$sPager = t3lib_parsehtml::substituteSubpart($sPager, "###LINKPREV###",	$aLinks["prev"], FALSE, FALSE);
			$sPager = t3lib_parsehtml::substituteSubpart($sPager, "###LINKNEXT###",	$aLinks["next"], FALSE, FALSE);
			$sPager = t3lib_parsehtml::substituteSubpart($sPager, "###LINKLAST###",	$aLinks["last"], FALSE, FALSE);

			// generating window
			$sWindow = "";
			if(!empty($this->aPager["window"])) {

				#$sWindow = t3lib_parsehtml::getSubpart($sPager, "###WINDOW###");
				$sWindow = t3lib_parsehtml::getSubpart($aTemplate["pager"], "###WINDOW###");
				$sLinkNo = t3lib_parsehtml::getSubpart($sWindow, "###NORMAL###");
				$sLinkAct = t3lib_parsehtml::getSubpart($sWindow, "###ACTIVE###");
				$sMoreBefore = t3lib_parsehtml::getSubpart($sWindow, "###MORE_BEFORE###");
				$sMoreAfter = t3lib_parsehtml::getSubpart($sWindow, "###MORE_AFTER###");

				if($this->aPager["alwaysfullwidth"] === TRUE) {
					if(trim(($sLinkDisabled = t3lib_parsehtml::getSubpart($sWindow, "###DISABLED###"))) === "") {
						$this->oForm->mayday(
							"RENDERLET " . $this->_getType() . " <b>" . $this->_getName() . "</b> - In your pager's template, you have to provide a <b>###DISABLED###</b> subpart inside the <b>###WINDOW###</b> subpart when defining <b>/window/alwaysFullWidth=TRUE</b>"
						);
					}
				}

				$aLinks = array();
				
				reset($this->aPager["window"]);
				if(key($this->aPager["window"]) > 2 && trim($sMoreBefore) !== "") {
					$aLinks[] = $sMoreBefore;
				}

				reset($this->aPager["window"]);
				while(list($iPageNum, $sLink) = each($this->aPager["window"])) {
					
					if($sLink === FALSE) {
						$aLinks[] = $this->oForm->_parseTemplateCode(
							$sLinkAct,
							array(
								"link" => $sLink,
								"page" => $iPageNum,
							)
						);
					} elseif($this->aPager["page"] == $iPageNum) {
						$aLinks[] = $this->oForm->_parseTemplateCode(
							$sLinkAct,
							array(
								"link" => $sLink,
								"page" => $iPageNum,
							)
						);
					} else {
						$aLinks[] = $this->oForm->_parseTemplateCode(
							$sLinkNo,
							array(
								"link" => $sLink,
								"page" => $iPageNum,
							)
						);
					}
				}
				
				end($this->aPager["window"]);
				if((key($this->aPager["window"]) < ($this->aPager["pagemax"] - 1)) && trim($sMoreAfter) !== "") {
					$aLinks[] = $sMoreAfter;
 				}
				
				$sLinks = implode(" ", $aLinks);
				
				$sWindow = t3lib_parsehtml::substituteSubpart($sWindow, "###WINDOWLINKS###", $sLinks, FALSE, FALSE);
			}

			$sPager = t3lib_parsehtml::substituteSubpart($sPager, "###WINDOW###", $sWindow, FALSE, FALSE);
		} else {
			$sPager = "";
		}

		$aTemplate["html"] = $this->oForm->_parseTemplateCode(
			$aTemplate["html"],
			array(
				"PAGER" => $sPager
			),
			array(),
			FALSE
		);
	}
	
	function _renderList_displaySortHeaders(&$aTemplate) {

		reset($this->aOColumns);
		while(list($sColumn, ) = each($this->aOColumns)) {

			$sSubpart = "###SORT_" . $sColumn . "###";
			
			if(($sSortHtml = trim(t3lib_parsehtml::getSubpart($aTemplate["html"], $sSubpart))) != "") {

				$sSortHtml = $this->oForm->_substLLLInHtml($sSortHtml);

				if($this->aOColumns[$sColumn]->_defaultTrue("/sort") === TRUE) {

					$sNewDir = "asc";
					$sLabelDir = "";
					$sCssClass = "sort-no";

					if(($this->aLimitAndSort["sortby"] === $sColumn)) {
						
						if($this->aLimitAndSort["sortdir"] === "desc") {
							
							$sNewDir = "asc";
							$sLabelDir = (($this->aTemplate["default"] === TRUE) ? " [Z-a]" : "");
							$sCssClass = "sort-act-desc";

						} else {
							
							$sNewDir = "desc";

							$sLabelDir = (($this->aTemplate["default"] === TRUE) ? " [a-Z]" : "");
							$sCssClass = "sort-act-asc";
						}
					}

					$sLink = $this->_buildLink(array(
						"sort" => $sColumn . "-" . $sNewDir
					));

					if(($sHeader = $this->getListHeader($sColumn)) !== "") {
						$sAccesTitle = "{LLL:EXT:ameos_formidable/api/base/rdt_lister/res/locallang/locallang.xml:sortby} &quot;" . strip_tags($sHeader) . "&quot; {LLL:EXT:ameos_formidable/api/base/rdt_lister/res/locallang/locallang.xml:sort." . $sNewDir . "}";
					} else {
						$sAccesTitle = "{LLL:EXT:ameos_formidable/api/base/rdt_lister/res/locallang/locallang.xml:sort} {LLL:EXT:ameos_formidable/api/base/rdt_lister/res/locallang/locallang.xml:sort." . $sNewDir . "}";
					}

					#$sAccesTitle = "{LLL:EXT:ameos_formidable/api/base/rdt_lister/res/locallang/locallang.xml:sortby} &quot;" . $sHeader . "&quot; {LLL:EXT:ameos_formidable/api/base/rdt_lister/res/locallang/locallang.xml:sort." . $sNewDir . "}";
					$sTag = "<a href=\"" . $sLink . "\" title=\"" . $sAccesTitle . "\" class=\"" . $sColumn . "_sort " . $sCssClass . "\">" . $sSortHtml . $sLabelDir . "</a>";
				} else {
					$sTag = $sSortHtml;
				}

				$aTemplate["html"] = t3lib_parsehtml::substituteSubpart(
					$aTemplate["html"],
					$sSubpart,
					$sTag,
					FALSE,
					FALSE
				);
			}
		}
	}
	
	function &_getTemplate() {

		$aRes = array(
			"default" => FALSE,
			"html" => "",
			"styles" => "",
			"cssfile" => "",
			"pager" => "",
		);
		
		if((($aTemplate = $this->_navConf("/template")) === FALSE) || (($this->bNoTemplate = $this->_defaultFalse("/template/notemplate")) === TRUE)) {

			if($this->bNoTemplate === FALSE) {
				// no template defined, building default lister template
				$aRes = $this->__buildDefaultTemplate();
				$this->bDefaultTemplate = TRUE;
				$this->bNoTemplate = FALSE;
			} else {
				$aRes = array(
					"default" => FALSE,
				);

				$this->bDefaultTemplate = FALSE;
				$this->bNoTemplate = TRUE;
			}
		} else {

			if(is_array($aTemplate) && array_key_exists("path", $aTemplate)) {
				if($this->oForm->isRunneable($aTemplate["path"])) { 
					$aTemplate["path"] = $this->callRunneable($aTemplate["path"]);
				}
			} else {
				$this->oForm->mayday("RENDERLET LISTER <b>" . $this->_getName() . "</b> - Template defined, but <b>/template/path</b> is missing. Please check your XML configuration");
			}

			if(is_array($aTemplate) && array_key_exists("subpart", $aTemplate)) {
				if($this->oForm->isRunneable($aTemplate["subpart"])) {
					$aTemplate["subpart"] = $this->callRunneable($aTemplate["subpart"]);
				}
			} else {
				$this->oForm->mayday("RENDERLET LISTER <b>" . $this->_getName() . "</b> - Template defined, but <b>/template/subpart</b> is missing. Please check your XML configuration");
			}

			$aTemplate["path"] = $this->oForm->toServerPath($aTemplate["path"]);


			if(file_exists($aTemplate["path"])) {
				if(is_readable($aTemplate["path"])) {
					$aRes["html"] = t3lib_parsehtml::getSubpart(
						t3lib_div::getUrl($aTemplate["path"]),
						$aTemplate["subpart"]
					);

					if(trim($aRes["html"]) === "") {
						$this->_autoTemplateMayday($aTemplate, TRUE);
					}
				} else {
					$this->oForm->mayday("RENDERLET LISTER <b>" . $this->_getName() . "</b> - the given template file '<b>" . $aTemplate["path"] . "</b>' isn't readable. Please check permissions for this file.");
				}
			} else {
				$this->_autoTemplateMayday($aTemplate);
			}

			/* managing styles and CSS file */

			if(array_key_exists("cssfile", $aTemplate)) {
				if($this->oForm->isRunneable($aTemplate["cssfile"])) {
					$aTemplate["cssfile"] = $this->callRunneable($aTemplate["cssfile"]);
				}
				
				$aRes["cssfile"] = $this->oForm->toWebPath($aTemplate["cssfile"]);
			}

			/* styles after css-file to eventually override css-file directives */
			if(array_key_exists("styles", $aTemplate)) {
				if($this->oForm->isRunneable($aTemplate["styles"])) {
					$aTemplate["styles"] = $this->callRunneable($aTemplate["styles"]);
				}

				$aRes["styles"] = $aTemplate["styles"];
			}


			/* get pager */

			if(($aPagerTemplate = $this->_navConf("/pager/template")) !== FALSE) {

				if(is_array($aPagerTemplate) && array_key_exists("path", $aPagerTemplate)) {
					if($this->oForm->isRunneable($aPagerTemplate["path"])) { 
						$aPagerTemplate["path"] = $this->callRunneable($aPagerTemplate["path"]);
					}
				} else {
					$this->oForm->mayday("RENDERLET LISTER <b>" . $this->_getName() . "</b> - Template for PAGER is defined, but <b>/pager/template/path</b> is missing. Please check your XML configuration");
				}

				if(is_array($aPagerTemplate) && array_key_exists("subpart", $aPagerTemplate)) {
					if($this->oForm->isRunneable($aPagerTemplate["subpart"])) {
						$aPagerTemplate["subpart"] = $this->callRunneable($aPagerTemplate["subpart"]);
					}
				} else {
					$this->oForm->mayday("RENDERLET LISTER <b>" . $this->_getName() . "</b> - Template for PAGER defined, but <b>/pager/template/subpart</b> is missing. Please check your XML configuration");
				}

				$aPagerTemplate["path"] = $this->oForm->toServerPath($aPagerTemplate["path"]);

				if(file_exists($aPagerTemplate["path"])) {
					if(is_readable($aPagerTemplate["path"])) {
						$aRes["pager"] = t3lib_parsehtml::getSubpart(
							t3lib_div::getUrl($aPagerTemplate["path"]),
							$aPagerTemplate["subpart"]
						);

						if(trim($aRes["pager"]) === "") {
							$this->_autoPagerMayday($aPagerTemplate, TRUE);
						}

					} else {
						$this->oForm->mayday("RENDERLET LISTER <b>" . $this->_getName() . "</b> - the given template file for PAGER '<b>" . $aPagerTemplate["path"] . "</b>' isn't readable. Please check permissions for this file.");
					}
				} else {
					$this->_autoPagerMayday($aPagerTemplate);
				}
			}
		}

		if($aRes["styles"] !== "") {

			if($this->bDefaultTemplate === TRUE) {
				$sComment = "Stylesheet of DEFAULT TEMPLATE for renderlet:LISTER " . $this->_getName();
				$sKey = "tx_ameosformidable_renderletlister_defaultstyle";
			} else {
				$sComment = "Dynamic stylesheet for renderlet:LISTER " . $this->_getName();
				$sKey = "tx_ameosformidable_renderletlister_dynamicstyle_" . $this->_getName();
			}

			$this->oForm->additionalHeaderData(
				$this->oForm->inline2TempFile($aRes["styles"], "css", $sComment),
				$sKey
			);
		}

		if($aRes["cssfile"] !== "") {
			$this->oForm->additionalHeaderData(
				"<!-- CSS file for renderlet:LISTER " . $this->_getName() . " -->\n<link rel=\"stylesheet\" type=\"text/css\" href=\"" . $aRes["cssfile"] . "\" />\n\n",
				"tx_ameosformidable_renderletlister_cssfile_" . $this->_getName()
			);
		}

		reset($aRes);
		return $aRes;
	}

	function _autoTemplateMayday($aTemplate, $bSubpartError = FALSE) {

		/* ERROR message with automatic generated TEMPLATE and CSS */
		$aDefaultTemplate = $this->__buildDefaultTemplate("#" . $this->_getElementHtmlId());

		$sDefaultTemplate = htmlspecialchars($aDefaultTemplate["html"]);
		$sDefaultStyles = htmlspecialchars($aDefaultTemplate["styles"]);

		$sError = $bSubpartError ?
			"RENDERLET LISTER <b>" . $this->_getName() . "</b> - the given SUBPART '<b>" . $aTemplate["subpart"] . "</b>' doesn't exists."
			: "RENDERLET LISTER <b>" . $this->_getName() . "</b> - the given TEMPLATE FILE '<b>" . $aTemplate["path"] . "</b>' doesn't exists.";

		$sMessage =<<<ERRORMESSAGE

	<div>{$sError}</div>
	<hr />
	<div>If you're going to create this template, these automatically generated html template and styles might be usefull</div>
	<h2>Automatic LIST template</h2>
	<div>Copy/paste this in <b>{$aTemplate["path"]}</b></div>
	<div style='color: black; background-color: #e6e6fa; border: 2px dashed #4682b4; font-family: Courier;'>
		<br />
<pre>
&lt;!-- {$aTemplate["subpart"]} begin--&gt;
		
{$sDefaultTemplate}
		
&lt;!-- {$aTemplate["subpart"]} end--&gt;
</pre>
		<br /><br />
	</div>
	<h2>Automatic CSS</h2>
	<div style='color: black; background-color: #e6e6fa; border: 2px dashed #4682b4;'><pre>{$sDefaultStyles}</pre></div>

ERRORMESSAGE;
		
		$this->oForm->mayday($sMessage);
	}

	function _autoPagerMayday($aTemplate, $bSubpartError = FALSE) {

		/* ERROR message for PAGER with automatic generated TEMPLATE */

		$sDefaultPager = htmlspecialchars($this->__getDefaultPager());

		$sError = $bSubpartError ?
			"RENDERLET LISTER <b>" . $this->_getName() . "</b> - the given SUBPART for PAGER '<b>" . $aTemplate["subpart"] . "</b>' doesn't exists."
			: "RENDERLET LISTER <b>" . $this->_getName() . "</b> - the given TEMPLATE FILE for PAGER '<b>" . $aTemplate["path"] . "</b>' doesn't exists.";

		$sMessage =<<<ERRORMESSAGE

	<div>{$sError}</div>
	<hr />
	<div>If you're going to create this template, these automatically generated html template might be usefull</div>
	<h2>Automatic PAGER template</h2>
	<div>Copy/paste this in <b>{$aTemplate["path"]}</b></div>
	<div style='color: black; background-color: #e6e6fa; border: 2px dashed #4682b4; font-family: Courier;'>
		<br />
<pre>
&lt;!-- {$aTemplate["subpart"]} begin--&gt;
{$sDefaultPager}
&lt;!-- {$aTemplate["subpart"]} end--&gt;
</pre>
<br /><br />
	</div>

ERRORMESSAGE;
		
		$this->oForm->mayday($sMessage);
	}

	function &__getDefaultPager() {
		$sPath = $this->sExtPath . "res/html/default-template.html";
		$sSubPart = "###LISTPAGER###";

		return t3lib_parsehtml::getSubpart(
			t3lib_div::getUrl($sPath),
			$sSubPart
		);
	}

	function &__buildDefaultTemplate($sCssPrefix = ".ameosformidable-rdtlister-defaultwrap") {

		$aRes = array(
			"default" => TRUE,
			"html" => "",
			"styles" => "",
			"cssfile" => "",
			"pager" => "",
		);

		$aHtml = array(
			"TOP" => array(),
			"DATA" => array(
				"ROW1" => array(),
				"ROW2" => array(),
				"ROWACT" => array(),
			),
		);

		$sPath		= $this->sExtPath . "res/html/default-template.html";
		$sSubpart	= "###LIST###";
		
		$aRes["html"] = t3lib_parsehtml::getSubpart(
			t3lib_div::getUrl($sPath),
			$sSubpart
		);

		/* including default styles in external CSS */
		
		$aRes["styles"] = $this->oForm->_parseTemplateCode(
			t3lib_parsehtml::getSubpart(
				t3lib_div::getUrl($sPath),
				"###STYLES###"
			),
			array(
				"PREFIX" => $sCssPrefix,
				"EXTPATH" => "/" . $this->sExtRelPath
			),
			array(),
			FALSE
		);

		/*END of CSS */



		$sTopColumn = t3lib_parsehtml::getSubpart($aRes["html"],		"###TOPCOLUMN###");
		$sDataColumn1 = t3lib_parsehtml::getSubpart($aRes["html"],		"###DATACOLUMN1###");
		$sDataColumn2 = t3lib_parsehtml::getSubpart($aRes["html"],		"###DATACOLUMN2###");
		$sDataColumnAct = t3lib_parsehtml::getSubpart($aRes["html"],	"###DATACOLUMNACT###");
		
		reset($this->aOColumns);
		while(list($sColName,) = each($this->aOColumns)) {
			
			if($this->_defaultTrue("/columns/listheaders") === TRUE) {

				// building sorting header for this column

				if(($sHeader = $this->getListHeader($sColName)) === FALSE) {
					$sHeader = "{" . $sColName . ".label}";
				}

				$aHtml["TOP"][]	= $this->oForm->_parseTemplateCode(
					$sTopColumn,
					array(
						"COLNAME"		=> $sColName,
						"COLCONTENT"	=> "<!-- ###SORT_" . $sColName . "### begin-->" . $sHeader . "<!-- ###SORT_" . $sColName . "### end-->"
					),
					array(),	// exclude
					FALSE		// bClearNotUsed
				);
			}

			// building data cells for this column
			$aTemp = array(
				"COLNAME"		=> $sColName,
				"COLCONTENT"	=> "{" . $sColName . "}",
			);

			$aHtml["DATA"]["ROW1"][]	= $this->oForm->_parseTemplateCode(
				$sDataColumn1,
				$aTemp,
				array(),
				FALSE
			);

			$aHtml["DATA"]["ROW2"][]	= $this->oForm->_parseTemplateCode(
				$sDataColumn2,
				$aTemp,
				array(),
				FALSE
			);

			$aHtml["DATA"]["ROWACT"][]	= $this->oForm->_parseTemplateCode(
				$sDataColumnAct,
				$aTemp,
				array(),
				FALSE
			);
		}

		$aRes["html"] = t3lib_parsehtml::substituteSubpart($aRes["html"], "###STYLES###", "", FALSE, FALSE);
		$aRes["html"] = t3lib_parsehtml::substituteSubpart($aRes["html"], "###DATACOLUMN1###", implode("", $aHtml["DATA"]["ROW1"]), FALSE, FALSE);
		$aRes["html"] = t3lib_parsehtml::substituteSubpart($aRes["html"], "###DATACOLUMN2###", implode("", $aHtml["DATA"]["ROW2"]), FALSE, FALSE);
		$aRes["html"] = t3lib_parsehtml::substituteSubpart($aRes["html"], "###DATACOLUMNACT###", implode("", $aHtml["DATA"]["ROWACT"]), FALSE, FALSE);
		$aRes["html"] = t3lib_parsehtml::substituteSubpart($aRes["html"], "###TOPCOLUMN###", implode("", $aHtml["TOP"]), FALSE, FALSE);

		$aRes["html"] = $this->oForm->_parseTemplateCode(
			$aRes["html"],
			array(
				"NBCOLS" => sizeOf($this->aOColumns)
			),
			array(),
			FALSE
		);

		/* RETRIEVING pager */
		
		$aRes["pager"] = $this->__getDefaultPager();

		return $aRes;
	}




	function initChilds($bReInit = FALSE) {
		$this->_initColumns();
	}

	function _initColumns() {
		
		if($this->aOColumns === FALSE) {
			
			if(($aColumns = $this->_navConf("/columns")) !== FALSE && is_array($aColumns)) {

				$this->aOColumns = array();
				$aColKeys = array_keys($aColumns);
				reset($aColKeys);
				while(list(, $sTagName) = each($aColKeys)) {

					if($this->oForm->_defaultTrue("/process", $aColumns[$sTagName])) {
						
						$aColumns[$sTagName]["type"] = str_replace("renderlet:", "", $aColumns[$sTagName]["type"]);

						if(array_key_exists("name", $aColumns[$sTagName]) && (trim($aColumns[$sTagName]["name"]) != "")) {
							$sName = trim($aColumns[$sTagName]["name"]);
							$bAnonymous = FALSE;
						} else {
							$sName = $this->oForm->_getAnonymousName($aColumns[$sTagName]);
							$this->aElement["columns"][$sTagName]["name"] = $sName;
							$aColumns[$sTagName]["name"] = $sName;
							$bAnonymous = TRUE;
						}

						$oRdt =& $this->oForm->_makeRenderlet(
							$aColumns[$sTagName],
							$this->sXPath . "columns/" . $sTagName . "/",
							$bChilds = TRUE,
							$this,
							$bAnonymous,
							$sNamePrefix
						);

						$sAbsName = $oRdt->getAbsName();
						$sName = $oRdt->getName();

						$this->oForm->aORenderlets[$sAbsName] =& $oRdt;
						unset($oRdt);

						// columns are localy stored without prefixing, of course
						$this->aOColumns[$sName] =& $this->oForm->aORenderlets[$sAbsName];
					}
				}
			} else {
				$this->aOColumns = array();
			}
		}
	}

	function _getElementHtmlName($sName = FALSE) {
		
		$sRes = parent::_getElementHtmlName($sName);
		$aData =& $this->oForm->oDataHandler->_getListData();

		if(!empty($aData)) {
			$sRes .= "[" . $aData["uid"] . "]";
		}

		return $sRes;
	}
	
	function _getElementHtmlNameWithoutFormId($sName = FALSE) {
		$sRes = parent::_getElementHtmlNameWithoutFormId($sName);
		$aData =& $this->oForm->oDataHandler->_getListData();

		if(!empty($aData)) {
			$sRes .= "[" . $aData["uid"] . "]";
		}

		return $sRes;
	}

	function _getElementHtmlId($sId = FALSE) {
		
		$sRes = parent::_getElementHtmlId($sId);

		/*$aData =& $this->oForm->oDataHandler->_getListData();
		if(!empty($aData)) {
			$sRes .= AMEOSFORMIDABLE_NESTED_SEPARATOR_BEGIN . $aData["uid"] . AMEOSFORMIDABLE_NESTED_SEPARATOR_END;
		}*/

		return $sRes;
	}

	function &_refineRow(&$aRow) {

		$sUid = $aRow["uid"];

		if(is_array($aRow)) {
			$aColKeys = array_keys($this->aOColumns);
			reset($aColKeys);
			while(list(,$sName) = each($aColKeys)) {
				
				$this->aOColumns[$sName]->doBeforeIteration($this);

				if(array_key_exists($sName, $aRow)) {
					
					$sAbsName = $this->aOColumns[$sName]->getAbsName();

					if(array_key_exists($sAbsName, $this->oForm->aPreRendered)) {
						$aRow[$sAbsName] = $this->oForm->aPreRendered[$sAbsName];
					} else {
						$this->aRdtByRow[$sUid][$sName] = $this->aOColumns[$sName]->_getElementHtmlId();

						if($this->aOColumns[$sName]->_activeListable()) {

							$aRow[$sName] = $this->oForm->oRenderer->processHtmlBag(
								$this->aOColumns[$sName]->renderWithForcedValue($aRow[$sName]),
								$this->aOColumns[$sName]
							);
						} else {
							$aRow[$sName] = $this->oForm->oRenderer->processHtmlBag(
								$this->aOColumns[$sName]->renderReadOnlyWithForcedValue($aRow[$sName]),
								$this->aOColumns[$sName]
							);
						}
					}
				} else {
					// not in the data row
					// probably a virtual column

					// calling _getValue() here, as value has to be evaluated for each row
					$mValue = $this->aOColumns[$sName]->getValue();

					if($this->aOColumns[$sName]->_activeListable()) {

						$this->aRdtByRow[$sUid][$sName] = $this->aOColumns[$sName]->_getElementHtmlId();

						$aRow[$sName] = $this->oForm->oRenderer->processHtmlBag(
							$this->aOColumns[$sName]->renderWithForcedValue($mValue),
							$this->aOColumns[$sName]
						);
					} else {

						// calling _getValue() here, as value has to be evaluated for each row
						$mValue = $this->aOColumns[$sName]->getValue();

						$aRow[$sName] = $this->oForm->oRenderer->processHtmlBag(
							$this->aOColumns[$sName]->renderReadOnlyWithForcedValue($mValue),
							$this->aOColumns[$sName]
						);
					}
				}

				$this->aOColumns[$sName]->doAfterIteration();
			}
		} else {
			$aRow = array();
		}

		reset($aRow);
		return $aRow;
	}

	function _getPage() {
		
		if($this->bResetPager !== TRUE) {
			if($this->aLimitAndSort !== FALSE) {
				return $this->aLimitAndSort["curpage"];
			} else {
				$aGet = $this->oForm->oDataHandler->_G();
				$sName = $this->_getElementHtmlId();

				if(array_key_exists($sName, $aGet) && array_key_exists("page", $aGet[$sName])) {
					return (($iPage = intval($aGet[$sName]["page"])) >= 1) ? $iPage : 1;
				}
			}
		}

		return 1;
	}

	function _getSortColAndDirection() {

		if($this->aLimitAndSort !== FALSE) {
			$aRes = array(
				"col" => $this->aLimitAndSort["sortby"],
				"dir" => $this->aLimitAndSort["sortdir"],
			);
		} else {

			$aRes = array(
				"col" => "",
				"dir" => "",
			);

			$aGet = $this->oForm->oDataHandler->_G();
			$sName = $this->_getElementHtmlId();

			if(array_key_exists($sName, $aGet) && array_key_exists("sort", $aGet[$sName])) {
				$sSort = $aGet[$sName]["sort"];
				$aSort = explode("-", $sSort);

				if(sizeOf($aSort) == 2) {
					$sCol = $aSort[0];
					if(!array_key_exists($sCol, $this->aOColumns)) {
						$sCol = array_shift(array_keys($this->aOColumns));
					}

					$sDir = $aSort[1];
					if(!in_array($sDir, array("asc", "desc"))) {
						$sDir = "asc";
					}
				}

				$aRes = array(
					"col" => $sCol,
					"dir" => $sDir
				);
			} elseif($this->_navConf("/pager/sort") !== FALSE) {
				
				if(($sSortCol = $this->_navConf("/pager/sort/column")) !== FALSE) {
					if($this->oForm->isRunneable($sSortCol)) {
						$aRes["col"] = $this->callRunneable($sSortCol);
					} else {
						$aRes["col"] = $sSortCol;
					}
				}

				if(($sSortDir = $this->_navConf("/pager/sort/direction")) !== FALSE) {
					if($this->oForm->isRunneable($sSortDir)) {
						$aRes["dir"] = $this->callRunneable($sSortDir);
					} else {
						$aRes["dir"] = $sSortDir;
					}
				}
			}
		}

		return $aRes;
	}

	function mayHaveChilds() {
		return TRUE;
	}

	function hasChilds() {
		return TRUE;
	}

	function _activeListable() {
		return $this->oForm->_defaultTrue("/activelistable/", $this->aElement);
	}
	
	function _renderOnly() {
		return TRUE;
	}

	function cleanBeforeSession() {

		$aKeys = array_keys($this->aOColumns);
		reset($aKeys);
		while(list(, $sKey) = each($aKeys)) {
			if(is_object($this->aOColumns[$sKey])) {
				$sName = $this->aOColumns[$sKey]->getAbsName();
				unset($this->aOColumns[$sKey]);
				$this->aOColumns[$sKey] = $sName;
				$this->oForm->aORenderlets[$sName]->cleanBeforeSession();
			}
		}

		$this->baseCleanBeforeSession();
		unset($this->oForm);
	}

	function awakeInSession(&$oForm) {
		
		parent::awakeInSession($oForm);
		
		$aKeys = array_keys($this->aOColumns);

		reset($aKeys);
		while(list(, $sKey) = each($aKeys)) {
			$sName = $this->aOColumns[$sKey];
			if(!is_object($sName)) {
				unset($this->aOColumns[$sKey]);
				$this->aOColumns[$sKey] =& $this->oForm->aORenderlets[$sName];
			}
		}
	}

	function getCurRowNum() {
		return $this->iCurRowNum;
	}
	
	function getCurRow() {
		return $this->__aCurRow;
	}
	
	function isIterating() {
		return $this->getCurRowNum() !== FALSE;
	}
	
	function isIterable() {
		return TRUE;
	}
}


	if (defined("TYPO3_MODE") && $TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["ext/ameos_formidable/api/base/rdt_lister/api/class.tx_rdtlister.php"])	{
		include_once($TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["ext/ameos_formidable/api/base/rdt_lister/api/class.tx_rdtlister.php"]);
	}
?>
